package whf.framework.util;

import java.beans.PropertyDescriptor;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

import whf.framework.config.ApplicationConfig;

/**
 * @author wanghaifeng
 *
 */
public class StringUtils {
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	
	private StringUtils(){}
	
	public static String capitalize(final String input){
		if(input == null) return null;
		if(input.length() == 1) return input.toUpperCase();
		return input.substring(0,1).toUpperCase()+input.substring(1);
	}
	
	public static int compare(final String input1, final String input2){
		if(input1 == null && input2 == null) return 0;
		if(input1 != null && input2 == null) return 1;
		if(input1 == null && input2 != null) return -1;
		return input1.compareTo(input2);
	}
	
	public static boolean isEmpty(final String input){
		return input == null || input.trim().equals("");
	}
	
	public static boolean startsWith(final String source, final String prefix){
		if(source == null){
			return false;
		}else {
			return source.startsWith(prefix);
		}
	}
	
	public static boolean endsWith(final String source, final String suffix){
		if(source == null) return false;
		return source.endsWith(suffix);
	}
	
	public static boolean isNumeric(final String input) {
		try{
			Double.parseDouble(input);
			return true;
		}catch(Exception e){
			return false;
		}
	}
	
	public static boolean equalsIgnoreCase(final String input1, final String input2){
		if(input1 == null && input2 == null) return true;
		if(input1 == null && input2 != null) return false;
		if(input2 == null && input1 != null) return false;
		return input1.trim().equalsIgnoreCase(input2.trim());
	}
	
	public static boolean equals(final String input1, final String input2){
		if(input1 == null || input2 == null) return false;
		return input1.trim().equals(input2);
	}
	
	public static String[] split(final String input, final String p){
		if(input == null) return null;
		return org.apache.commons.lang.StringUtils.split(input, p);
	}
	
	/**
	 * 使用正则表达式分隔字符串，忽略空值
	 * @modify wanghaifeng Nov 30, 2006 11:19:34 PM
	 * @param input
	 * @param p
	 * @return
	 */
	public static String[] split2(final String input, final String p){
		java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("["+p+"]+");
		return pattern.split(input);
	}
	
	public static boolean isAlpha(final String ch){
		return org.apache.commons.lang.StringUtils.isAlpha(ch);
	}
	
	public static boolean isAlphanumeric(final String ch){
		return org.apache.commons.lang.StringUtils.isAlphanumeric(ch);
	}
	
	public static boolean isAsciiPrintable(final String ch){
		return org.apache.commons.lang.StringUtils.isAsciiPrintable(ch);
	}
	
	public static String replace(final String input, final String s1, final String s2){
		if(input == null) return null;
		return org.apache.commons.lang.StringUtils.replace(input, s1, s2);
	}
	
	/**
	 * 替换{0}这样的字符串，只需要一次可以大批量的替换
	 * @modify wanghaifeng Aug 30, 2006 11:42:05 PM
	 * @param reservedWords
	 * @param input
	 * @return
	 */
	public static String replace2(final Map<String, String> reservedWords, final String input){
		if(reservedWords == null || reservedWords.isEmpty() || isEmpty(input)) return input;
		StringBuffer result = new StringBuffer(200);
		StringBuffer buff = new StringBuffer(20);
		for (int index = 0; index < input.length(); index++) {
			char c = input.charAt(index);
			if (c == '{') {
				result.append(buff.substring(0, buff.length()));
				buff.delete(0, buff.length());
				buff.append(c);
			} else if (c == '}') {
				buff.append(c);
				String key = buff.substring(0, buff.length());
				String value = reservedWords.get(key);
				if (value != null) {
					result.append(value);
				} else {
					result.append(key);
				}
				buff.delete(0, buff.length());
			} else {
				buff.append(c);
			}
		}
		result.append(buff);
		return result.toString();
	}
	
	public static Date parseDate(String input){
		try{
			return sdf.parse(input);
		}catch(Exception e){
			return null;
		}
	}
	
	public static String buildToString(final Object obj){
		if(obj == null) return null;
		StringBuilder sb= new StringBuilder(obj.getClass().toString()).append("@");
		PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(obj.getClass());
		for(PropertyDescriptor descriptor: descriptors){
			if(TypeUtils.isImplementsFrom(descriptor.getPropertyType(), Collection.class)){
				sb.append(descriptor.getName()).append("=").append("Collection");
			} else {
				try{
					sb.append(descriptor.getName()).append(" = ").append(BeanUtils.getProperty(obj, descriptor.getName()));
				}catch(Exception e){
					sb.append(descriptor.getName()).append(" = ").append("Lazy Property");
				}
			}
			sb.append("\t");
		}
		return sb.toString();
	}
	
	/**
	 * 组装连接，把一个字符串合成一个合理的连接
	 * @modify wanghaifeng Aug 30, 2006 11:41:17 PM
	 * @param request
	 * @param uri
	 * @return
	 */
	public static String wrapHyperLink(HttpServletRequest request, String uri){
		if(uri == null) return "";
		if(!uri.toLowerCase().startsWith("http") && 
				!uri.toLowerCase().startsWith(request.getContextPath().toLowerCase())){
			if(!uri.startsWith("/")) uri = "/"+uri;
			uri = request.getContextPath()+uri;
		}
		return uri;
	}
	
	/**
	 * 将数组转变为条件的字符串
	 * @modify wanghaifeng Aug 30, 2006 11:44:59 PM
	 * @param ids
	 * @return
	 */
	public static String convertToString(final long[] ids) {
		if(ids == null || ids.length == 0) return null;
		StringBuilder sb = new StringBuilder();
		for(long id: ids){
			if(sb.length() > 0)
				sb.append(",");
			sb.append(id);
		}
		return sb.toString();
	}
	
	public static boolean match(final String patternString, final String input){
		PatternCompiler compiler = new Perl5Compiler();
		try{
			Pattern pattern = compiler.compile(patternString, Perl5Compiler.CASE_INSENSITIVE_MASK);
			PatternMatcher matcher = new Perl5Matcher();
			return matcher.matches(input, pattern);
		}catch(Exception ignore){
			//
		}
		return false;
	}
	
	/**
	 * 缺省操作，使用应用配置总的编码
	 * @modify wanghaifeng Mar 6, 2007 5:23:00 PM
	 * @param url
	 * @param props
	 * @return
	 */
	public static String buildURLString(final String url, final Map<String, String> props){
		try{
			return buildURLString(url, props, ApplicationConfig.getInstance().getEncoding());
		}catch(Exception e){
			return url;
		}
	}
	
	/**
	 * 构建URL字符串
	 * @modify wanghaifeng Mar 6, 2007 5:22:27 PM
	 * @param url		缺省的字符串
	 * @param props		相关属性
	 * @param enc		编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String buildURLString(final String url, final Map<String, String> props, final String enc) throws UnsupportedEncodingException{
		if(url == null) return null;
		if(props.isEmpty()) return url;
		StringBuilder sb = new StringBuilder(url);
		if(url.indexOf("?") <= 0){
			sb.append('?');
		}
		for(String key: props.keySet()){
			String value = props.get(key);
			if(value == null) continue;
			if(!sb.toString().endsWith("?") && !sb.toString().endsWith("&")){
				sb.append("&");
			}
			sb.append(URLEncoder.encode(key, enc)).append("=").append(URLEncoder.encode(value, enc));
		}
		return sb.toString();
	}
	
	/**
	 * 获取异常的详细情况
	 * @modify wanghaifeng Oct 19, 2006 10:24:09 AM
	 * @param t
	 * @return
	 */
	public static String getExceptionDetail(final Throwable t){
		CharArrayWriter writer = new CharArrayWriter();
		t.printStackTrace(new PrintWriter(writer));
		return writer.toString();
	}
	
	/**
	 * 格式化数字
	 * @modify wanghaifeng Mar 31, 2007 3:59:03 PM
	 * @param input
	 * @param pattern
	 * @return
	 */
	public static String format(final double input, final String pattern){
		NumberFormat nf = new DecimalFormat(pattern == null? "0.00":pattern);
		return nf.format(input);
	}
	
	/**
	 * 向左边填充字符串，直到全长为一定长度为止
	 * @param source 源字符串
	 * @param length 总长度
	 * @param chr 填充字符串
	 * @return 结果字符串
	 */
	public static String lpad(String source, final int length, final String chr){
		if(source == null) return null;
		if(chr == null || "".equals(chr)) return source;
		while(source.length() < length){
			source = chr + source;
		}
		if(source.length() > length) return source.substring(source.length() - length);
		return source;
	}
	
	public static void main(String[] arg) throws Exception {
		System.out.println(lpad("1234567", 5, "0"));
		String input = "king126.com";
		String source = input;
		// 检测输入的EMAIL地址是否以 非法符号"."或"@"作为起始字符
		java.util.regex.Pattern p = java.util.regex.Pattern
				.compile("^\\.|^\\@");
		java.util.regex.Matcher m = p.matcher(input);
		if (m.find()) {
			System.err.println("EMAIL地址不能以'.'或'@'作为起始字符");
		}
		// 检测是否以"www."为起始
		p = java.util.regex.Pattern.compile("^www\\.");
		m = p.matcher(input);
		if (m.find()) {
			System.out.println("EMAIL地址不能以'www.'起始");
		}
		// 检测是否包含非法字符
		p = java.util.regex.Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
		m = p.matcher(input);
		StringBuffer sb = new StringBuffer();
		boolean result = m.find();
		boolean deletedIllegalChars = false;
		while (result) {
			// 如果找到了非法字符那么就设下标记
			deletedIllegalChars = true;
			// 如果里面包含非法字符如冒号双引号等，那么就把他们消去，加到SB里面
			m.appendReplacement(sb, "");
			result = m.find();
		}
		m.appendTail(sb);
		input = sb.toString();
		if (deletedIllegalChars) {
			System.out.println("输入的EMAIL地址里包含有冒号、逗号等非法字符，请修改");
			System.out.println("您现在的输入为: " + source);
			System.out.println("修改后合法的地址应类似: " + input);
		}
	}

}
